﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WebApiCore;
using WebApiCore.Attributes;

namespace WebApiCore.Extension;

/// <summary>
/// 扫描配置所有集线器并注册
/// </summary>
public static class HubsExtension
{
	/// <summary>
	/// 扫描配置所有集线器并注册
	/// </summary>
	/// <param name="app"></param>
	public static void MapHubs(this IEndpointRouteBuilder app)
	{
		// 扫描所有集线器类型并且贴有 [MapHub] 特性且继承 Hub 或 Hub<>
        var hubs = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
            && u.IsDefined(typeof(MapHubAttribute), true)
            && (typeof(Hub).IsAssignableFrom(u) || u.HasImplementedRawGeneric(typeof(Hub<>))));

        if (!hubs.Any()) return;

		// 反射获取 MapHub 拓展方法
		var mapHubMethod = typeof(HubEndpointRouteBuilderExtensions).GetMethods().Where(u => u.Name == "MapHub" && u.IsGenericMethod && u.GetParameters().Length == 2).FirstOrDefault();
		if (mapHubMethod == null) return;

		foreach (Type hub in hubs)
		{
			// 解析集线器特性
			MapHubAttribute customAttribute = hub.GetCustomAttribute<MapHubAttribute>(inherit: true);

			// 注册集线器
			var hubEndpointConventionBuilder =
				mapHubMethod.MakeGenericMethod(hub).Invoke(null, new object[] { app, customAttribute.Pattern }) as HubEndpointConventionBuilder;
		}

		//string[] cls = new string[] { "WebApiCoreDemo"};
		//foreach (var item in cls)
		//{
		//	Assembly assembly = Assembly.Load(item);
		//	Register(assembly, app);
		//}
	}

	/// <summary>
	/// 反射获取 所有集线器 并注册
	/// </summary>
	/// <param name="assembly"></param>
	/// <param name="app"></param>
	private static void Register(Assembly assembly, IEndpointRouteBuilder app)
	{
		// 反射获取 所有集线器
		IEnumerable<Type> hubs = assembly.GetTypes().Where((Type u) => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(MapHubAttribute), inherit: true) && (typeof(Hub).IsAssignableFrom(u)));
		if (!hubs.Any())
		{
			return;
		}

		// 反射获取 MapHub 拓展方法
		var mapHubMethod = typeof(HubEndpointRouteBuilderExtensions).GetMethods().Where(u => u.Name == "MapHub" && u.IsGenericMethod && u.GetParameters().Length == 2).FirstOrDefault();
		if (mapHubMethod == null) return;

		foreach (Type hub in hubs)
		{
			// 解析集线器特性
			MapHubAttribute customAttribute = hub.GetCustomAttribute<MapHubAttribute>(inherit: true);

			// 注册集线器
			var hubEndpointConventionBuilder = 
				mapHubMethod.MakeGenericMethod(hub).Invoke(null, new object[] { app, customAttribute.Pattern }) as HubEndpointConventionBuilder;
		}
	}
}